#include <iostream>
using namespace std;
class AVLNode{
public:
int data;
int height;//结点的高度,叶子结点高度为1
AVLNode* lChild;
AVLNode* rChild;
public:
AVLNode(int data):data(data),height(1),lChild(0),rChild(0){}
};
class AVL{
public:
AVLNode* root;
public:
AVL(){
root = nullptr;
}
~AVL(){
delete root;
}
int height(AVLNode* root){
if(root){
return root->height;
}
return 0;
}
//找到树中最大结点并将其返回
AVLNode* finMaxNode(AVLNode* root){
//一直往右找
if(root->rChild){
root = root->rChild;
}
return root;
}
//找到树中最小结点并将其返回
AVLNode* finMinNode(AVLNode* root){
//一直往左找
if(root->lChild){
root = root->lChild;
}
return root;
}
//以p为根结点右旋转,返回新的根结点
AVLNode* llRotate(AVLNode* p){
AVLNode* pleft = p->lChild;
p->lChild = pleft->rChild;
pleft->rChild = p;
//结点的高度由该节点的子树唯一决定,所以只有子树发生变化的结点才需要更新高度值
pleft->height = max(height(pleft->lChild), height(pleft->rChild))+1;
p->height = max(height(p->lChild), height(p->rChild))+1;
return pleft;
}
//左旋转
AVLNode* rrRotate(AVLNode* p){
AVLNode* pright = p->rChild;
p->rChild = pright->lChild;
pright->lChild = p;
pright->height = max(height(pright->lChild), height(pright->rChild))+1;
p->height = max(height(p->lChild), height(p->rChild))+1;
return pright;
}
//先左,再右
AVLNode* lrRotate(AVLNode* p){
AVLNode* pleft = rrRotate(p->lChild);
return llRotate(p);
}
//先右,再左
AVLNode* rlRotate(AVLNode* p){
AVLNode* pright = llRotate(p->rChild);
return rrRotate(p);
}
//插入新结点,保持平衡
void insert(int data, AVLNode*& root){
if(!root){
root = new AVLNode(data);
}
else{
if(data < root->data){
insert(data, root->lChild);
//插入新结点后,如果打破平衡,则需要动态调整
if(height(root->lChild)-height(root->rChild) == 2){
if(data < root->lChild->data)
root = llRotate(root);
else
root = lrRotate(root);
}
}
else if(data > root->data){
insert(data, root->rChild);
//插入新结点后,如果打破平衡,则需要动态调整
if(height(root->rChild)-height(root->lChild) == 2){
if(data > root->rChild->data)
root = rrRotate(root);
else
root = rlRotate(root);
}
}
else{
cout << "AVL中已存在该值:" << data << endl;
}
}
//平衡后,需要更新根结点的高度值
root->height = max(height(root->lChild), height(root->rChild))+1;
}
//删除结点,保持平衡
void del(int data, AVLNode*& root){
if(data < root->data){
del(data, root->lChild);
//删除点之后,若AVL树失去平衡,则进行调整
if(height(root->rChild)-height(root->lChild) == 2){
AVLNode* r = root->rChild;
if(height(r->lChild) > height(r->rChild))
root = rlRotate(root);
else
root = rrRotate(root);
}
}
else if(data > root->data){
del(data, root->rChild);
//删除点之后,若AVL树失去平衡,则进行调整
if(height(root->lChild)-height(root->rChild) == 2){
AVLNode* l = root->lChild;
if(height(l->lChild) > height(l->rChild))
root = llRotate(root);
else
root = lrRotate(root);
}
}
else{
//此时root为要删除的点
if(root->lChild && root->rChild){
if(height(root->lChild) > height(root->rChild)){
// 如果root的左子树比右子树高;
// 则(01)找出root的左子树中的最大节点
// (02)将该最大节点的值赋值给root。
// (03)删除该最大节点。
// 这类似于用"root的左子树中最大节点"做"root"的替身;
// 采用这种方式的好处是:删除"tree的左子树中最大节点"之后,AVL树仍然是平衡的。
AVLNode* maxNode = finMaxNode(root->lChild);
root->data = maxNode->data;
del(maxNode->data, root->lChild);
}
else{
AVLNode* minNode = finMinNode(root->rChild);
root->data = minNode->data;
del(minNode->data, root->rChild);
}
}
else{
if(root->lChild){
root->data = root->lChild->data;
root->lChild = nullptr;
}
else if(root->rChild){
root->data = root->rChild->data;
root->rChild = nullptr;
}
else{
root = nullptr;//参数是引用,所以此处修改了主函数中的root值
}
}
}
}
void inOrder(AVLNode* root){
if(root){
inOrder(root->lChild);
cout << root->data << endl;
inOrder(root->rChild);
}
}
};
int main(){
AVL tree;
tree.insert(5, tree.root);
tree.insert(15, tree.root);
tree.insert(25, tree.root);
tree.insert(35, tree.root);
tree.insert(45, tree.root);
tree.insert(55, tree.root);
tree.del(55, tree.root);
tree.inOrder(tree.root);
return 0;
}
AVL平衡二叉树C++版
最新推荐文章于 2024-09-18 23:31:10 发布